<?php
/**
 *      [cdvphp!] (C)2012 - 2099 www.cdvphp.com
 *		核心函数封装类
 *
 *      $Id: function_core.php 2012-10-21 11:33:38 fanjiapeng $
 */

if(!defined('IN_CORE')) {
	exit('Access Denied');
}

define('IN_FUNCTION', true);

function dmicrotime() {
	return array_sum(explode(' ', microtime()));
}


function setglobal($key , $value) {
	global $_G;

	$k = explode('/', $key);
	switch (count($k)) {
		case 1: $_G[$k[0]] = $value; break;
		case 2: $_G[$k[0]][$k[1]] = $value; break;
		case 3: $_G[$k[0]][$k[1]][$k[2]] = $value; break;
		case 4: $_G[$k[0]][$k[1]][$k[2]][$k[3]] = $value; break;
		case 5: $_G[$k[0]][$k[1]][$k[2]][$k[3]][$k[4]] =$value; break;
	}

	return true;
}

function getglobal($key) {
	global $_G;

	$k = explode('/', $key);
	switch (count($k)) {
		case 1: return isset($_G[$k[0]]) ? $_G[$k[0]] : null; break;
		case 2: return isset($_G[$k[0]][$k[1]]) ? $_G[$k[0]][$k[1]] : null; break;
		case 3: return isset($_G[$k[0]][$k[1]][$k[2]]) ? $_G[$k[0]][$k[1]][$k[2]] : null; break;
		case 4: return isset($_G[$k[0]][$k[1]][$k[2]][$k[3]]) ? $_G[$k[0]][$k[1]][$k[2]][$k[3]] : null; break;
		case 5: return isset($_G[$k[0]][$k[1]][$k[2]][$k[3]][$k[4]]) ? $_G[$k[0]][$k[1]][$k[2]][$k[3]][$k[4]] : null; break;
	}

	return null;
}

function getgpc($k, $type='GP') {
	$type = strtoupper($type);

	switch($type) {
		case 'G': $var = &$_GET; break;
		case 'P': $var = &$_POST; break;
		case 'C': $var = &$_COOKIE; break;
		default:
			if(isset($_GET[$k])) {
				$var = &$_GET;
			} else {
				$var = &$_POST;
			}
			break;
	}

	return isset($var[$k]) ? $var[$k] : NULL;

}

function daddslashes($string, $force = 1) {
	if(is_array($string)) {
		$keys = array_keys($string);
		foreach($keys as $key) {
			$val = $string[$key];
			unset($string[$key]);
			$string[addslashes($key)] = daddslashes($val, $force);
		}
	} else {
		$string = addslashes(trim($string));
	}

	return $string;
}

function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
	$ckey_length = 4;
	$key = md5($key != '' ? $key : getglobal('config/security/authkey'));
	$keya = md5(substr($key, 0, 16));
	$keyb = md5(substr($key, 16, 16));
	$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';

	$cryptkey = $keya.md5($keya.$keyc);
	$key_length = strlen($cryptkey);

	$string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
	$string_length = strlen($string);

	$result = '';
	$box = range(0, 255);

	$rndkey = array();
	for($i = 0; $i <= 255; $i++) {
		$rndkey[$i] = ord($cryptkey[$i % $key_length]);
	}

	for($j = $i = 0; $i < 256; $i++) {
		$j = ($j + $box[$i] + $rndkey[$i]) % 256;
		$tmp = $box[$i];
		$box[$i] = $box[$j];
		$box[$j] = $tmp;
	}

	for($a = $j = $i = 0; $i < $string_length; $i++) {
		$a = ($a + 1) % 256;
		$j = ($j + $box[$a]) % 256;
		$tmp = $box[$a];
		$box[$a] = $box[$j];
		$box[$j] = $tmp;
		$result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
	}

	if($operation == 'DECODE') {
		if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
			return substr($result, 26);
		} else {
			return '';
		}
	} else {
		return $keyc.str_replace('=', '', base64_encode($result));
	}
}

function dhtmlspecialchars($string) {
	if(is_array($string)) {
		foreach($string as $key => $val) {
			$string[$key] = dhtmlspecialchars($val);
		}
	} else {
		$string = str_replace(array('&', '"', '<', '>'), array('&amp;', '&quot;', '&lt;', '&gt;'), trim($string));
		if(strpos($string, '&amp;#') !== false) {
			$string = preg_replace('/&amp;((#(\d{3,5}|x[a-fA-F0-9]{4}));)/', '&\\1', $string);
		}
	}

	return $string;
}

function dsetcookie($var, $value = '', $life = 0, $prefix = 1, $httponly = false) {

	global $_G;

	$config = $_G['config']['cookie'];

	$_G['cookie'][$var] = $value;
	$var = ($prefix ? $config['cookiepre'] : ''). $var;

	if($value == '' || $life < 0) {
		$value = '';
		$life = -1;
	}

	if(defined('IN_MOBILE')) {
		$httponly = false;
	}

	$life = $life > 0 ? $_G['timestamp'] + $life : ($life < 0 ? $_G['timestamp'] - 31536000 : 0);
	$path = $httponly && PHP_VERSION < '5.2.0' ? $config['cookiepath'].'; HttpOnly' : $config['cookiepath'];

	$secure = $_SERVER['SERVER_PORT'] == 443 ? 1 : 0;
	if(PHP_VERSION < '5.2.0') {
		setcookie($var, $value, $life, $path, $config['cookiedomain'], $secure);
	} else {
		setcookie($var, $value, $life, $path, $config['cookiedomain'], $secure, $httponly);
	}
}

function getcookie($key) {
	global $_G;
	return isset($_G['cookie'][$key]) ? $_G['cookie'][$key] : '';
}

function fileext($filename) {
	return addslashes(trim(substr(strrchr($filename, '.'), 1, 10)));
}

function formhash($specialadd = '') {
	global $_G;
	return substr(md5(substr($_G['timestamp'], 0, -7).$_G['config']['security']['authkey'].'cdvphp'.$_G['clientip'].$specialadd), 8, 8);
}

function checkrobot($useragent = '') {
	static $kw_spiders = array('bot', 'crawl', 'spider' ,'slurp', 'sohu-search', 'lycos', 'robozilla');
	static $kw_browsers = array('msie', 'netscape', 'opera', 'konqueror', 'mozilla');

	$useragent = strtolower(empty($useragent) ? $_SERVER['HTTP_USER_AGENT'] : $useragent);
	if(strpos($useragent, 'http://') === false && dstrpos($useragent, $kw_browsers)) return false;
	if(dstrpos($useragent, $kw_spiders)) return true;

	return false;
}

function dstrpos($string, &$arr, $returnvalue = false) {
	if(empty($string)) return false;
	foreach((array)$arr as $v) {
		if(strpos($string, $v) !== false) {
			$return = $returnvalue ? $v : true;
			return $return;
		}
	}

	return false;
}

function isemail($email) {
	return strlen($email) > 6 && preg_match("/^[\w\-\.]+@[\w\-\.]+(\.\w+)+$/", $email);
}

function strexists($string, $find) {
	return !(strpos($string, $find) === FALSE);
}

function lang($file, $langvar = null, $vars = '', $langpath = '') {
	global $_G;
	
	if(!$file) return FALSE;
	
	$path = '';
	if(strpos($file, '/') !== FALSE) {
		list($path, $file) = explode('/', $file);
	}

	$langpath = $langpath ? $langpath : FRAMEWORK_PATH;
	$key = $path == '' ? $file : $path.'_'.$file;

	if(!isset($_G['lang'][$key])) {
		include $langpath.'./language/'.($path == '' ? '' : $path.'/').'lang_'.$file.'.php';
		$_G['lang'][$key] = $lang;
	}

	$return = $langvar !== null ? (isset($_G['lang'][$key][$langvar]) ? $_G['lang'][$key][$langvar] : null) : $_G['lang'][$key];

	$searchs = $replaces = array();
	if($vars && is_array($vars)) {
		foreach($vars as $k => $v) {
			$searchs[] = '{'.$k.'}';
			$replaces[] = $v;
		}
	}

	return str_replace($searchs, $replaces, $return);
}

function checktplrefresh($maintpl, $subtpl, $timecompare, $templateid, $cachefile, $tpldir, $file) {
	static $tplrefresh, $timestamp;

	if($tplrefresh === null) {
		$tplrefresh = getglobal('config/output/tplrefresh');
		$timestamp  = getglobal('timestamp');
	}

	if(empty($timecompare) || $tplrefresh == 1 || ($tplrefresh > 1 && !($timestamp % $tplrefresh))) {
		if(empty($timecompare) || @filemtime(ROOT_PATH. $subtpl) > $timecompare) {
			require_once FRAMEWORK_PATH. './class/template.php';
			$template = new class_template();
			$template->parse_template($maintpl, $templateid, $tpldir, $file, $cachefile);
			return TRUE;
		}
	}

	return FALSE;
}

function template($file, $templateid = 0, $tpldir = '', $gettplfile = 0) {
	global $_G;

	$tpldir 	= $tpldir ? $tpldir : '';
	$templateid = $templateid ? $templateid : 'cdvphp';
	$filebak 	= $file;

	$tplfile = ($tpldir ? $tpldir. '/' : './'.$_G['config']['system']['view_path'].'/'). $file. '.'. $_G['config']['system']['template_suffix'];
	$cachefile = './data/view/'. $templateid. '_'. str_replace('/', '_', $file). '.tpl.php';

	if(!file_exists(ROOT_PATH. $tplfile)) {
		require_once FRAMEWORK_PATH. './class/error.php';
		class_error::template_error('template_notfound', ROOT_PATH. $tplfile);
	}

	if($gettplfile) {
		return $tplfile;
	}

	checktplrefresh($tplfile, $tplfile, @filemtime(ROOT_PATH. $cachefile), $templateid, $cachefile, $tpldir, $file);

	return ROOT_PATH. $cachefile;
}

function loadcache($cachenames, $force = false) {
	global $_G;
	static $loadedcache = array();
	$cachenames = is_array($cachenames) ? $cachenames : array($cachenames);
	$caches = array();
	foreach ($cachenames as $k) {
		if(!isset($loadedcache[$k]) || $force) {
			$caches[] = $k;
			$loadedcache[$k] = true;
		}
	}

	if(!empty($caches)) {
		$cachedata = cachedata($caches);
		foreach($cachedata as $cname => $data) {
			if($cname == 'setting') {
				$_G['setting'] = $data;
			} elseif(strpos($cname, 'usergroup_'.$_G['groupid']) !== false) {
				$_G['cache'][$cname] = $_G['group'] = $data;
			} elseif($cname == 'style_default') {
				$_G['cache'][$cname] = $_G['style'] = $data;
			} elseif($cname == 'grouplevels') {
				$_G['grouplevels'] = $data;
			} else {
				$_G['cache'][$cname] = $data;
			}
		}
	}
	return true;
}

function cachedata($cachenames) {
	global $_G;
	static $isfilecache, $allowmem;

	if(!isset($isfilecache)) {
		$isfilecache = getglobal('config/cache/type') == 'file';
		$allowmem = memory('check');
	}

	$data = array();
	$cachenames = is_array($cachenames) ? $cachenames : array($cachenames);
	if($allowmem) {
		$newarray = array();
		foreach ($cachenames as $name) {
			$data[$name] = memory('get', $name);
			if($data[$name] === null) {
				$data[$name] = null;
				$newarray[] = $name;
			}
		}
		if(empty($newarray)) {
			return $data;
		} else {
			$cachenames = $newarray;
		}
	}

	if($isfilecache) {
		$lostcaches = array();
		foreach($cachenames as $cachename) {
			if(!@include_once(DISCUZ_ROOT.'./data/cache/cache_'.$cachename.'.php')) {
				$lostcaches[] = $cachename;
			}
		}
		if(!$lostcaches) {
			return $data;
		}
		$cachenames = $lostcaches;
		unset($lostcaches);
	}
	$query = DB::query("SELECT * FROM ".get_table('common_syscache')." WHERE cname IN ('".implode("','", $cachenames)."')");
	while($syscache = DB::fetch($query)) {
		$data[$syscache['cname']] = $syscache['ctype'] ? unserialize($syscache['data']) : $syscache['data'];
		$allowmem && (memory('set', $syscache['cname'], $data[$syscache['cname']]));
		if($isfilecache) {
			$cachedata = '$data[\''.$syscache['cname'].'\'] = '.var_export($data[$syscache['cname']], true).";\n\n";
			if($fp = @fopen(DISCUZ_ROOT.'./data/cache/cache_'.$syscache['cname'].'.php', 'wb')) {
				fwrite($fp, "<?php\n//Discuz! cache file, DO NOT modify me!\n//Identify: ".md5($syscache['cname'].$cachedata.$_G['config']['security']['authkey'])."\n\n$cachedata?>");
				fclose($fp);
			}
		}
	}

	foreach($cachenames as $name) {
		if($data[$name] === null) {
			$data[$name] = null;
			$allowmem && (memory('set', $name, array()));
		}
	}

	return $data;
}

function dmktime($date) {
	if(strpos($date, '-')) {
		$time = explode('-', $date);
		return mktime(0, 0, 0, $time[1], $time[2], $time[0]);
	}
	return 0;
}

function dimplode($array) {
	if(!empty($array)) {
		return "'".implode("','", is_array($array) ? $array : array($array))."'";
	} else {
		return 0;
	}
}

//系统报错
function system_error($message, $show = true, $save = true, $halt = true) {
	require_once FRAMEWORK_PATH. './class/error.php';
	class_error::system_error($message, $show, $save, $halt);
}

//加载lib文件
function libfile($libname, $folder = '') {
	$libpath = FRAMEWORK_PATH. $folder;
	if(strstr($libname, '/')) {
		list($pre, $name) = explode('/', $libname);
		return realpath("{$libpath}/{$pre}/{$pre}_{$name}.php");
	} else {
		return realpath("{$libpath}/{$libname}.php");
	}
}

function dstrlen($str) {
	if(strtolower(getglobal('config/output/charset')) != 'utf-8') {
		return strlen($str);
	}
	$count = 0;
	for($i = 0; $i < strlen($str); $i++){
		$value = ord($str[$i]);
		if($value > 127) {
			$count++;
			if($value >= 192 && $value <= 223) $i++;
			elseif($value >= 224 && $value <= 239) $i = $i + 2;
			elseif($value >= 240 && $value <= 247) $i = $i + 3;
	    	}
    		$count++;
	}

	return $count;
}

function cutstr($string, $length, $dot = ' ...') {
	if(strlen($string) <= $length) {
		return $string;
	}

	$pre = chr(1);
	$end = chr(1);
	$string = str_replace(array('&amp;', '&quot;', '&lt;', '&gt;'), array($pre.'&'.$end, $pre.'"'.$end, $pre.'<'.$end, $pre.'>'.$end), $string);

	$strcut = '';
	if(strtolower(getglobal('config/output/charset')) == 'utf-8') {

		$n = $tn = $noc = 0;
		while($n < strlen($string)) {

			$t = ord($string[$n]);
			if($t == 9 || $t == 10 || (32 <= $t && $t <= 126)) {
				$tn = 1; $n++; $noc++;
			} elseif(194 <= $t && $t <= 223) {
				$tn = 2; $n += 2; $noc += 2;
			} elseif(224 <= $t && $t <= 239) {
				$tn = 3; $n += 3; $noc += 2;
			} elseif(240 <= $t && $t <= 247) {
				$tn = 4; $n += 4; $noc += 2;
			} elseif(248 <= $t && $t <= 251) {
				$tn = 5; $n += 5; $noc += 2;
			} elseif($t == 252 || $t == 253) {
				$tn = 6; $n += 6; $noc += 2;
			} else {
				$n++;
			}

			if($noc >= $length) {
				break;
			}

		}
		if($noc > $length) {
			$n -= $tn;
		}

		$strcut = substr($string, 0, $n);

	} else {
		for($i = 0; $i < $length; $i++) {
			$strcut .= ord($string[$i]) > 127 ? $string[$i].$string[++$i] : $string[$i];
		}
	}

	$strcut = str_replace(array($pre.'&'.$end, $pre.'"'.$end, $pre.'<'.$end, $pre.'>'.$end), array('&amp;', '&quot;', '&lt;', '&gt;'), $strcut);

	$pos = strrpos($strcut, chr(1));
	if($pos !== false) {
		$strcut = substr($strcut, 0, $pos);
	}

	return $strcut. $dot;
}

function dstripslashes($string) {
	if(empty($string)) return $string;
	if(is_array($string)) {
		foreach($string as $key => $val) {
			$string[$key] = dstripslashes($val);
		}
	} else {
		$string = stripslashes($string);
	}

	return $string;
}

function debug($var = null, $vardump = false) {
	echo '<pre>';
	if($var === null) {
		print_r($GLOBALS);
	} else {
		if($vardump) {
			var_dump($var);
		} else {
			print_r($var);
		}
	}
	exit();
}

function showmessage($message, $url = '', $extra_type = 0) {

	if($url) {
		if($extra_type == '301') {
			header("HTTP/1.1 301 Moved Permanently");
			header("location: ". str_replace('&amp;', '&', $url));
		} else {
			echo '<script type="text/javascript" reload="1">window.location.href=\''. str_replace("'", "\'", $url). '\';</script>';
		}
	}

	if($message) {
		echo $message;
	}
	
	exit();
}

function submitcheck($var, $specialadd = '', $allowget = 0) {
	global $_G;

	if(!$_G["gp_{$var}"]) {
		return FALSE;
	} else {
		if($allowget || ($_SERVER['REQUEST_METHOD'] == 'POST' && !empty($_G['gp_formhash']) && $_G['gp_formhash'] == formhash($specialadd) && empty($_SERVER['HTTP_X_FLASH_VERSION']) && (empty($_SERVER['HTTP_REFERER']) ||
		preg_replace("/https?:\/\/([^\:\/]+).*/i", "\\1", $_SERVER['HTTP_REFERER']) == preg_replace("/([^\:]+).*/", "\\1", $_SERVER['HTTP_HOST'])))) {
			return TRUE;
		} else {
			showmessage('submit_invalid');
		}
	}
}

function page($num, $perpage, $curpage = 1, $mpurl, $rewrite = 0, $maxpages = 0, $page = 10) {

	$a_name = ''; $url_format = 'page=';
	if(strpos($mpurl, '#') !== FALSE) {
		$a_strs = explode('#', $mpurl);
		$mpurl  = $a_strs[0];
		$a_name = '#'. $a_strs[1];
	}

	$lang['prev']  = lang('error', 'page_prevpage');
	$lang['next']  = lang('error', 'page_nextpage');
	$lang['first'] = lang('error', 'page_firstpage');
	$lang['end']   = lang('error', 'page_endpage');

	$multipage = '';

	if(!$rewrite) {
		$mpurl .= strpos($mpurl, '?') !== FALSE ? '&amp;' : '?';
	} else {
		$url_format = '/';
	}

	$realpages = 1;

	$curpage < 1 && $curpage = 1;
	$page -= strlen($curpage) - 1;

	$page <= 0 && $page = 1;

	if($num > $perpage) {

		$offset = floor($page * 0.5);

		$realpages = @ceil($num / $perpage);
		$pages = $maxpages && $maxpages < $realpages ? $maxpages : $realpages;

		if($page > $pages) {
			$from = 1;
			$to   = $pages;
		} else {
			$from = $curpage - $offset;
			$to   = $from + $page - 1;
			if($from < 1) {
				$to = $curpage + 1 - $from;
				$from = 1;
				if($to - $from < $page) {
					$to = $page;
				}
			} elseif($to > $pages) {
				$from = $pages - $page + 1;
				$to   = $pages;
			}
		}
		
		$multipage = ($curpage - $offset > 1 && $pages > $page ? "<a href=\"{$mpurl}{$url_format}1{$a_name}\">{$lang['first']}</a>" : '').
		($curpage > 1 ? '<a href="'.$mpurl.$url_format.($curpage - 1).$a_name.'" class="prev">'.$lang['prev'].'</a>' : '');
		for($i = $from; $i <= $to; $i++) {
			$multipage .= $i == $curpage ? '<a href="javascript:void(0)"><strong>'.$i.'</strong></a>' :
			'<a href="'.$mpurl.$url_format.$i.($i == $pages ? '#' : $a_name).'">'.$i.'</a>';
		}
		$multipage .= ($curpage < $pages ? '<a href="'.$mpurl.$url_format.($curpage + 1).$a_name.'">'.$lang['next'].'</a>' : ''). 
					  ($to < $pages ? '<a href="'.$mpurl.$url_format.$pages.$a_name.'">'.$lang['end'].'</a>' : '');
		$multipage = $multipage ? '<div class="page">'.$multipage.'</div>' : '';
	}
	
	$maxpage = $realpages;

	return $multipage;
}

function simplepage($num, $perpage, $curpage, $mpurl) {
	$simpage = '';
	$lang['next'] = lang('error', 'nextpage');
	$lang['prev'] = lang('error', 'prevpage');

	$realpages = @ceil($num / $perpage);
	$next = $curpage < $realpages ? '<a href="'.$mpurl.'&amp;page='.($curpage + 1).'" class="next">'.$lang['next'].'</a>' : '';
	$prev = $curpage > 1 ? '<a href="'.$mpurl.'&amp;page='.($curpage - 1).'" class="prev">'.$lang['prev'].'</a>' : '';

	if($next || $prev) {
		$simpage = '<div class="page">'.$prev.$next.'</div>';
	}

	return $simpage;
}

function runlog($file, $message, $halt=0) {
	global $_G;

	$nowurl = $_G['siteurl'] ? $_G['siteurl'] : $_G['phpself'];
	$log = date('Y-m-d H:i:s', $_G['timestamp'])."\t".$_G['clientip']."\t{$_G['referer']}\t{$nowurl}\t".str_replace(array("\r", "\n"), array(' ', ' '), trim($message))."\n";

	writelog($file, $log);
	if($halt) {
		exit();
	}
}

function writelog($file, $log) {
	global $_G;
	$yearmonth = date('Ym', $_G['timestamp']);
	$logdir = ROOT_PATH. './data/logs/';
	$logfile = $logdir. $yearmonth. '_'. $file. '.php';

	if(@filesize($logfile) > 2048000) {
		$dir = opendir($logdir);
		$length = strlen($file);
		$maxid = $id = 0;
		while($entry = readdir($dir)) {
			if(strpos($entry, $yearmonth.'_'.$file) !== false) {
				$id = intval(substr($entry, $length + 8, -4));
				$id > $maxid && $maxid = $id;
			}
		}
		closedir($dir);

		$logfilebak = $logdir. $yearmonth. '_'. $file. '_'.($maxid + 1). '.php';
		@rename($logfile, $logfilebak);
	}

	if($fp = @fopen($logfile, 'a')) {
		@flock($fp, 2);
		$log = is_array($log) ? $log : array($log);
		foreach($log as $tmp) {
			fwrite($fp, "<?PHP exit;?>\t".str_replace(array('<?', '?>'), '', $tmp)."\n");
		}
		fclose($fp);
	}
}

function stripsearchkey($string) {
	$string = trim($string);
	$string = str_replace('*', '%', addcslashes($string, '%_'));
	$string = str_replace('_', '\_', $string);

	return $string;
}

function dmkdir($dir, $mode = 0777, $makeindex = TRUE) {
	$stats = false;

	if(!is_dir($dir)) {
		dmkdir(dirname($dir));
		$stats = @mkdir($dir, $mode);
		if(!empty($makeindex) && $stats) {
			$stats = @touch($dir. '/index.html'); 
			$stats = $stats ? @chmod($dir. '/index.html', 0777) : $stats;
		}
	}

	return $stats;
}

function sizecount($size) {
	if($size >= 1073741824) {
		$size = round($size / 1073741824 * 100) / 100 . ' GB';
	} elseif($size >= 1048576) {
		$size = round($size / 1048576 * 100) / 100 . ' MB';
	} elseif($size >= 1024) {
		$size = round($size / 1024 * 100) / 100 . ' KB';
	} else {
		$size = $size . ' Bytes';
	}

	return $size;
}

function model($model_name = '', $force = true) {
	global $_G;

	$str_modelname  = $_G['config']['system']['model_path'];
	$str_cachemodel = ROOT_PATH. "/data/model/{$model_name}.php";
	$str_model		= ROOT_PATH. "./{$str_modelname}/"._dir_classname($model_name).".php";
	$str_content 	= '';
	
	if(is_readable($str_model) == FALSE) {
		if($force) {
			class_error::template_error('require_model_error', $str_model);
		} else {
			return $force;
		}
	}

	if(!file_exists($str_cachemodel) || filemtime($str_model) > @filemtime($str_cachemodel)) {
		$str_content = file_get_contents($str_model);
		$str_content = preg_replace("/\s+class\s+({$model_name})/i", PHP_EOL. "class \${1}___model", $str_content, 1);
		file_put_contents($str_cachemodel, $str_content);
	}

	$str_modelname = md5($str_cachemodel);
	if(!isset($_G['class'][$str_modelname])) {
		$model_name .= '___model';
		require($str_cachemodel);
		$_G['class'][$str_modelname] = new $model_name();
	}

	unset($str_cachemodel, $str_model, $str_content);

	return $_G['class'][$str_modelname];
}

function isphone($number) {
	return preg_match('/^\d{11,13}$/i', $number);
}

function multimerge($arr_source, $arr_merge) {
	if (is_array($arr_merge) && count($arr_merge)) {
		foreach ($arr_merge as $k => $v) {
			$arr_source[$k] = isset($arr_source[$k]) ? $arr_source[$k] : array();
			$arr_source[$k] = (is_array($v) && count($v)) ? multimerge($arr_source[$k], $v) : $v;
		}
    }

    return $arr_source;
}

function random($length, $numeric = 0) {
	PHP_VERSION < '4.2.0' ? mt_srand((double)microtime() * 1000000) : mt_srand();
	$seed = base_convert(md5(print_r($_SERVER, 1).microtime()), 16, $numeric ? 10 : 35);
	$seed = $numeric ? (str_replace('0', '', $seed).'012340567890') : ($seed.'zZ'.strtoupper($seed));
	$hash = '';
	$max = strlen($seed) - 1;
	for($i = 0; $i < $length; $i++) {
		$hash .= $seed[mt_rand(0, $max)];
	}
	return $hash;
}

// 以_分隔目录
function _dir_classname($str_classname = '') {

	$str_load_classname = $str_classname;

	if(($int_count = strrpos($str_classname, '_')) !== FALSE) {
		$str_load_classname = dirname(str_replace('_', '/', $str_classname)) . '/';
		$str_load_classname .= substr($str_classname, $int_count + 1);
	}

	return $str_load_classname;
}
?>
